﻿//"The contents of this file are subject to the Mozilla Public License
//Version 1.1 (the "License"); you may not use this file except in
//compliance with the License. You may obtain a copy of the License at
//http://www.mozilla.org/MPL/

//Software distributed under the License is distributed on an "AS IS"
//basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
//License for the specific language governing rights and limitations
//under the License.

//The Original Code is TSharp.

//The Initial Developer of the Original Code is Mar3ek (http://mar3ek.wordpress.com).
//Portions created by Mar3ek are Copyright (C) 2010
//Mar3ek (http://mar3ek.wordpress.com). All Rights Reserved.

//Contributor(s): ______________________________________.

//Alternatively, the contents of this file may be used under the terms
//of the _____ license (the  "[___] License"), in which case the
//provisions of [______] License are applicable instead of those
//above.  If you wish to allow use of your version of this file only
//under the terms of the [____] License and not to allow others to use
//your version of this file under the MPL, indicate your decision by
//deleting  the provisions above and replace  them with the notice and
//other provisions required by the [___] License.  If you do not delete
//the provisions above, a recipient may use your version of this file
//under either the MPL or the [___] License."

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Xml.Linq;

namespace TSharp
{
    public partial class Twitter
    {
        #region Friends & followers

        #region GetFriendsIds

        ///<summary>
        /// Returns an array of numeric IDs for every user the specified user is following.
        ///</summary>
        ///<param name="screenName">The screen name of the user for whom to return results for</param>
        ///<exception cref="ArgumentNullException"></exception>
        ///<returns>List of user IDs</returns>
        public Collection<ulong> GetFriendsIds(string screenName)
        {
            if (string.IsNullOrEmpty(screenName)) throw new ArgumentNullException("screenName");

            var result = SendRequest(RequestMethod.Get,
                                        "https://api.twitter.com/1/friends/ids.xml",
                                        true,
                                        new KeyValuePair<string, string>("screen_name", screenName));
            var doc = XDocument.Parse(result);

            var idsElement = doc.Element("id_list");

            var friendsIds = new Collection<ulong>();
            // ReSharper disable PossibleNullReferenceException
            if (idsElement != null)
                friendsIds = new Collection<ulong>(idsElement.Element("ids").Elements("id").Select(idElement => ulong.Parse(idElement.Value)).ToList());
            // ReSharper restore PossibleNullReferenceException
            return friendsIds;
        }

        ///<summary>
        /// Returns an array of numeric IDs for every user the specified user is following.
        ///</summary>
        ///<param name="userId">The ID of the user for whom to return results for</param>
        ///<exception cref="ArgumentOutOfRangeException"></exception>
        ///<returns>List of user IDs</returns>
        public Collection<ulong> GetFriendsIds(ulong userId)
        {
            if (userId < 1) throw new ArgumentOutOfRangeException("userId");

            var result = SendRequest(RequestMethod.Get,
                                        "https://api.twitter.com/1/friends/ids.xml",
                                        true,
                                        new KeyValuePair<string, string>("user_id", userId.ToString()));
            var doc = XDocument.Parse(result);

            var idsElement = doc.Element("id_list");

            var friendsIds = new Collection<ulong>();

            // ReSharper disable PossibleNullReferenceException
            if (idsElement != null)
                friendsIds = new Collection<ulong>(idsElement.Element("ids").Elements("id").Select(idElement => ulong.Parse(idElement.Value)).ToList());
            // ReSharper restore PossibleNullReferenceException
            return friendsIds;
        }

        ///<summary>
        /// Returns an array of numeric IDs for every user the specified user is following.
        ///</summary>
        ///<param name="user">The user for whom to return results for</param>
        ///<returns>List of user IDs</returns>
        /// <exception cref="ArgumentNullException"><paramref name="user" /> is <c>null</c>.</exception>
        public Collection<ulong> GetFriendsIds(TwitterUser user)
        {
            if (user == null) throw new ArgumentNullException("user");

            return GetFriendsIds(user.ScreenName);
        } 
        
        /// <summary>
        /// Returns a list of numeric IDs for every user the specified user is following.
        /// </summary>
        /// <param name="screenName">The screen name of the user for whom to return results for</param>
        /// <param name="cursor">Causes the list of connections to be broken into pages of no more than 5000 IDs at a time</param>
        /// <param name="previousCursor">Start index of the previous page</param>
        /// <param name="nextCursor">Start index of the next page</param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        /// <returns>List of user IDs</returns>
        public Collection<ulong> GetFriendsIds(string screenName, long cursor, out long previousCursor, out long nextCursor)
        {
            if (string.IsNullOrEmpty(screenName)) throw new ArgumentNullException("screenName");
            if (cursor < -1) throw new ArgumentOutOfRangeException("cursor");

            var result = SendRequest(RequestMethod.Get,
                                        "https://api.twitter.com/1/friends/ids.xml",
                                        true,
                                        new KeyValuePair<string, string>("cursor", cursor.ToString()),
                                        new KeyValuePair<string, string>("screen_name", screenName));

            var doc = XDocument.Parse(result);

            var idsElement = doc.Element("id_list");

            var list = new Collection<ulong>();
            previousCursor = 0;
            nextCursor = 0;
            if (idsElement != null)
            {
                // ReSharper disable PossibleNullReferenceException
                list = new Collection<ulong>(idsElement.Element("ids").Elements("id").Select(idElement => ulong.Parse(idElement.Value)).ToList());
                previousCursor = long.Parse(idsElement.Element("previous_cursor").Value);
                nextCursor = long.Parse(idsElement.Element("next_cursor").Value);
                // ReSharper restore PossibleNullReferenceException
            }

            return list;
        }

        /// <summary>
        /// Returns a list of numeric IDs for every user the specified user is following.
        /// </summary>
        /// <param name="user">The user for whom to return results</param>
        /// <param name="cursor">Causes the list of connections to be broken into pages of no more than 5000 IDs at a time</param>
        /// <param name="previousCursor">Start index of the previous page</param>
        /// <param name="nextCursor">Start index of the next page</param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        /// <returns>List of user IDs</returns>
        public Collection<ulong> GetFriendsIds(TwitterUser user, long cursor, out long previousCursor, out long nextCursor)
        {
            if (user == null) throw new ArgumentNullException("user");
            if (cursor < -1) throw new ArgumentOutOfRangeException("cursor");

            var result = SendRequest(RequestMethod.Get,
                                        "https://api.twitter.com/1/friends/ids.xml",
                                        true,
                                        new KeyValuePair<string, string>("cursor", cursor.ToString()),
                                        new KeyValuePair<string, string>("screen_name", user.ScreenName));

            var doc = XDocument.Parse(result);

            var idsElement = doc.Element("id_list");

            var list = new Collection<ulong>();
            previousCursor = 0;
            nextCursor = 0;
            if (idsElement != null)
            {
                // ReSharper disable PossibleNullReferenceException
                list = new Collection<ulong>(idsElement.Element("ids").Elements("id").Select(idElement => ulong.Parse(idElement.Value)).ToList());
                previousCursor = long.Parse(idsElement.Element("previous_cursor").Value);
                nextCursor = long.Parse(idsElement.Element("next_cursor").Value);
                // ReSharper restore PossibleNullReferenceException
            }

            return list;
        }

        /// <summary>
        /// Returns a list of numeric IDs for every user the specified user is following.
        /// </summary>
        /// <param name="userId">The ID of the user for whom to return results for</param>
        /// <param name="cursor">Causes the list of connections to be broken into pages of no more than 5000 IDs at a time</param>
        /// <param name="previousCursor">Start index of the previous page</param>
        /// <param name="nextCursor">Start index of the next page</param>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        /// <returns>List of user IDs</returns>
        public Collection<ulong> GetFriendsIds(ulong userId, long cursor, out long previousCursor, out long nextCursor)
        {
            if (userId < 1) throw new ArgumentOutOfRangeException("userId");
            if (cursor < -1) throw new ArgumentOutOfRangeException("cursor");

            var result = SendRequest(RequestMethod.Get,
                                        "https://api.twitter.com/1/friends/ids.xml",
                                        true,
                                        new KeyValuePair<string, string>("cursor", cursor.ToString()),
                                        new KeyValuePair<string, string>("user_id", userId.ToString()));

            var doc = XDocument.Parse(result);

            var idsElement = doc.Element("id_list");

            var list = new Collection<ulong>();
            previousCursor = 0;
            nextCursor = 0;
            if (idsElement != null)
            {
                // ReSharper disable PossibleNullReferenceException
                list = new Collection<ulong>(idsElement.Element("ids").Elements("id").Select(idElement => ulong.Parse(idElement.Value)).ToList());
                previousCursor = long.Parse(idsElement.Element("previous_cursor").Value);
                nextCursor = long.Parse(idsElement.Element("next_cursor").Value);
                // ReSharper restore PossibleNullReferenceException
            }
            return list;
        }

        #endregion

        #region GetFollowersIds

        ///<summary>
        /// Returns an array of numeric IDs for every user the specified user is following.
        ///</summary>
        ///<param name="screenName">The screen name of the user for whom to return results for</param>
        ///<exception cref="ArgumentNullException"></exception>
        ///<returns>List of userIDs</returns>
        public Collection<ulong> GetFollowersIds(string screenName)
        {
            if (string.IsNullOrEmpty(screenName)) throw new ArgumentNullException("screenName");

            var result = SendRequest(RequestMethod.Get,
                                        "https://api.twitter.com/1/followers/ids.xml",
                                        true,
                                        new KeyValuePair<string, string>("screen_name", screenName));
            var doc = XDocument.Parse(result);

            var idsElement = doc.Element("id_list");

            var followersIds = new Collection<ulong>();

            // ReSharper disable PossibleNullReferenceException
            if (idsElement != null)
                followersIds = new Collection<ulong>(idsElement.Element("ids").Elements("id").Select(idElement => ulong.Parse(idElement.Value)).ToList());
            // ReSharper restore PossibleNullReferenceException
            return followersIds;
        }

        ///<summary>
        /// Returns an array of numeric IDs for every user the specified user is following.
        ///</summary>
        ///<param name="userId">The ID of the user for whom to return results for</param>
        ///<exception cref="ArgumentOutOfRangeException"></exception>
        ///<returns>List of user IDs</returns>
        public Collection<ulong> GetFollowersIds(ulong userId)
        {
            if (userId < 1) throw new ArgumentOutOfRangeException("userId");

            var result = SendRequest(RequestMethod.Get,
                                        "https://api.twitter.com/1/followers/ids.xml",
                                        true,
                                        new KeyValuePair<string, string>("user_id", userId.ToString()));
            var doc = XDocument.Parse(result);

            var idsElement = doc.Element("id_list");

            var followersIds = new Collection<ulong>();

            // ReSharper disable PossibleNullReferenceException
            if (idsElement != null)
                followersIds = new Collection<ulong>(idsElement.Element("ids").Elements("id").Select(idElement => ulong.Parse(idElement.Value)).ToList());
            // ReSharper restore PossibleNullReferenceException
            return followersIds;
        }

        ///<summary>
        /// Returns an array of numeric IDs for every user the specified user is following.
        ///</summary>
        ///<param name="user">The user for whom to return results for</param>
        ///<returns>List of user IDs</returns>
        /// <exception cref="ArgumentNullException"><paramref name="user" /> is <c>null</c>.</exception>
        public Collection<ulong> GetFollowersIds(TwitterUser user)
        {
            if (user == null) throw new ArgumentNullException("user");

            return GetFollowersIds(user.ScreenName);
        }

        /// <summary>
        /// Returns a list of numeric IDs for every user following the specified user.
        /// </summary>
        /// <param name="screenName">The screen name of the user for whom to return results for</param>
        /// <param name="cursor">Causes the list of connections to be broken into pages of no more than 5000 IDs at a time</param>
        /// <param name="previousCursor">Start index of the previous page</param>
        /// <param name="nextCursor">Start index of the next page</param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        /// <returns>List of user IDs</returns>
        public Collection<ulong> GetFollowersIds(string screenName, long cursor, out long previousCursor, out long nextCursor)
        {
            if (string.IsNullOrEmpty(screenName)) throw new ArgumentNullException("screenName");
            if (cursor < -1) throw new ArgumentOutOfRangeException("cursor");

            var result = SendRequest(RequestMethod.Get,
                                        "https://api.twitter.com/1/followers/ids.xml",
                                        true,
                                        new KeyValuePair<string, string>("cursor", cursor.ToString()),
                                        new KeyValuePair<string, string>("screen_name", screenName));

            var doc = XDocument.Parse(result);

            var idsElement = doc.Element("id_list");

            var list = new Collection<ulong>();
            previousCursor = 0;
            nextCursor = 0;
            if (idsElement != null)
            {
                // ReSharper disable PossibleNullReferenceException
                list = new Collection<ulong>(idsElement.Element("ids").Elements("id").Select(idElement => ulong.Parse(idElement.Value)).ToList());
                previousCursor = long.Parse(idsElement.Element("previous_cursor").Value);
                nextCursor = long.Parse(idsElement.Element("next_cursor").Value);
                // ReSharper restore PossibleNullReferenceException
            }

            return list;
        }

        /// <summary>
        /// Returns a list of numeric IDs for every user following the specified user.
        /// </summary>
        /// <param name="user">The user for whom to return results</param>
        /// <param name="cursor">Causes the list of connections to be broken into pages of no more than 5000 IDs at a time</param>
        /// <param name="previousCursor">Start index of the previous page</param>
        /// <param name="nextCursor">Start index of the next page</param>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        /// <exception cref="ArgumentNullException"></exception>
        /// <returns>List of user IDs</returns>
        public Collection<ulong> GetFollowersIds(TwitterUser user, long cursor, out long previousCursor, out long nextCursor)
        {
            if (user == null) throw new ArgumentNullException("user");
            if (cursor < -1) throw new ArgumentOutOfRangeException("cursor");

            var result = SendRequest(RequestMethod.Get,
                                        "https://api.twitter.com/1/followers/ids.xml",
                                        true,
                                        new KeyValuePair<string, string>("cursor", cursor.ToString()),
                                        new KeyValuePair<string, string>("screen_name", user.ScreenName));

            var doc = XDocument.Parse(result);

            var idsElement = doc.Element("id_list");

            var list = new Collection<ulong>();
            previousCursor = 0;
            nextCursor = 0;
            if (idsElement != null)
            {
                // ReSharper disable PossibleNullReferenceException
                list = new Collection<ulong>(idsElement.Element("ids").Elements("id").Select(idElement => ulong.Parse(idElement.Value)).ToList());
                previousCursor = long.Parse(idsElement.Element("previous_cursor").Value);
                nextCursor = long.Parse(idsElement.Element("next_cursor").Value);
                // ReSharper restore PossibleNullReferenceException
            }

            return list;
        }

        /// <summary>
        /// Returns a list of numeric IDs for every user following the specified user.
        /// </summary>
        /// <param name="userId">The ID of the user for whom to return results for</param>
        /// <param name="cursor">Causes the list of connections to be broken into pages of no more than 5000 IDs at a time</param>
        /// <param name="previousCursor">Start index of the previous page</param>
        /// <param name="nextCursor">Start index of the next page</param>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        /// <returns>List of user IDs</returns>
        public Collection<ulong> GetFollowersIds(long userId, long cursor, out long previousCursor, out long nextCursor)
        {
            if (userId < 1) throw new ArgumentOutOfRangeException("userId");
            if (cursor < -1) throw new ArgumentOutOfRangeException("cursor");

            var result = SendRequest(RequestMethod.Get,
                                        "https://api.twitter.com/1/followers/ids.xml",
                                        true,
                                        new KeyValuePair<string, string>("cursor", cursor.ToString()),
                                        new KeyValuePair<string, string>("user_id", userId.ToString()));

            var doc = XDocument.Parse(result);

            var idsElement = doc.Element("id_list");

            var list = new Collection<ulong>();
            previousCursor = 0;
            nextCursor = 0;
            if (idsElement != null)
            {
                // ReSharper disable PossibleNullReferenceException
                list = new Collection<ulong>(idsElement.Element("ids").Elements("id").Select(idElement => ulong.Parse(idElement.Value)).ToList());
                previousCursor = long.Parse(idsElement.Element("previous_cursor").Value);
                nextCursor = long.Parse(idsElement.Element("next_cursor").Value);
                // ReSharper restore PossibleNullReferenceException
            }
            return list;
        } 

        #endregion

        #endregion
    }
}
